﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BskLeague.Models;

namespace BskLeague.Controllers
{
    public class TeamController : Controller
    {

        BskLeagueDB _db = new BskLeagueDB();
/*****************************************************************/
        //Playing teams
        // GET: /Team?letter=A
        public ActionResult Index(char? letter, int? from, int? take)
        {
            @ViewBag.LettersList = IndexList();
            letter = (letter != null) ? letter : @ViewBag.LettersList[0] ;
            from = (from != null) ? from : 0;
            take = (take != null) ? take : 5;
            @ViewBag.From = from;
            @ViewBag.Take = take;
            @ViewBag.Letter = letter;

            List<Team> teams;

            /*letter==0 means that all of the teams should be counted, while
            letter!=0 is supposed to find only those teams, which names start with given letter*/
            if (letter != '0')
            {   
                //getting selected teams info
                string l = letter.ToString();          //new string variable, because..
                teams = _db.Teams
                    .Where(t => t.TeamName.StartsWith(l))   //..letter.ToString() not allowed here
                    .OrderBy(t => t.TeamName)
                    .Skip((int)from)
                    .Take((int)take)
                    .Select(t => t).ToList();

                //counting total number of teams, with name starting at "letter" value
                @ViewBag.TotalItemsCount = _db.Teams
                    .Where(t => t.TeamName.StartsWith(l))
                    .OrderBy(t => t.TeamName)
                    .Count();

                //counting won/lost matches for each team selected
                @ViewBag.Matches = countMatches(teams);
            }
            else
            {
                teams = _db.Teams.OrderBy(t => t.TeamName)
                .Skip((int)from)
                .Take((int)take)
                .Select(t => t).ToList();

                @ViewBag.TotalItemsCount = _db.Teams
                .OrderBy(t => t.TeamName)
                .Count();

            }
            //counting won/lost matches for each team
            @ViewBag.Matches = countMatches(teams);

            return View(teams);
        }
/*****************************************************************/
        //Details of a single team
        // GET: /Team/Details/1
        public ActionResult Details(int id, int? from, int? take)
        {
            //checking parameters
            from = (from != null) ? from : 0;
            take = (take != null) ? take : 5;
            ViewBag.From = from;
            ViewBag.Take = take;
            ViewBag.Id = id;

            Team team = _db.Teams.Find(id);

            //selected team's players data
            var stp = _db.SeasonTeamPlayers
                .OrderBy(s=>s.Player.PlayerSurname).ToList()
                .Where(s => s.TeamId == id)
                .Select(s => new { s.Player.PlayerId, PlayerName = s.Player.PlayerName + " " + s.Player.PlayerSurname });
            ViewBag.Players = stp.Select(s=>s.PlayerName).ToList();
            ViewBag.PlayersID = stp.Select(s => s.PlayerId).ToList();

            //count total number of matches played in
            ViewBag.TotalItemsCount = _db.Matchs
                .Where(s => s.Team1.TeamId == team.TeamId || s.Team2.TeamId == team.TeamId)
                .ToList().Count;

            //last matches data
            var matches = _db.Matchs
                    .OrderByDescending(s => s.Date)
                    .Where(s => s.Team1.TeamId == team.TeamId || s.Team2.TeamId == team.TeamId)
                    .Skip((int)from)
                    .Take((int)take)
                    .Select(s => new {s.Date, s.Team1, s.Team2, s.FinalScore1, s.FinalScore2, s.Place.stadiumName, s.Place.stadiumId, s.Season.SeasonName, s.Round}).ToList();
            
            //moving data to ViewBags
            ViewBag.Date = matches.Select(s => s.Date.ToShortDateString()).ToList();
            ViewBag.Place = matches.Select(s => s.stadiumName).ToList();
            ViewBag.PlaceID = matches.Select(s => s.stadiumId).ToList();
            ViewBag.Season = matches.Select(s => s.SeasonName).ToList();
            ViewBag.Round = matches.Select(s => s.Round).ToList();

            ViewBag.Oponent = new List<string>();
            ViewBag.OponentID = new List<int>();
            ViewBag.OponentPts = new List<int>();
            ViewBag.TeamPts = new List<int>();
            foreach (var item in matches)
            {
                if(item.Team1.TeamId == id)
                {
                    ViewBag.OponentID.Add(item.Team2.TeamId);
                    ViewBag.Oponent.Add(item.Team2.TeamName);
                    ViewBag.OponentPts.Add(item.FinalScore2);
                    ViewBag.TeamPts.Add(item.FinalScore1);
                }
                else
                {
                    ViewBag.OponentID.Add(item.Team1.TeamId);
                    ViewBag.Oponent.Add(item.Team1.TeamName);
                    ViewBag.OponentPts.Add(item.FinalScore1);
                    ViewBag.TeamPts.Add(item.FinalScore2);
                }
            };

            //Won/lost matches
            ViewBag.Matches = countMatches(team);

            return View(team);
        }
/*****************************************************************/
        //List, that contains first letters of teams names, that have been found in database
        private List<char> IndexList()
        {
            List<char> lista;
            lista = _db.Teams
                .OrderBy(t => t.TeamName).ToList()
                .GroupBy(t => t.TeamName.Substring(0,1).ToUpper())
                .Select(grp => grp.First())
                .Select(t=>t.TeamName[0])
                .ToList();
            return lista;
        }
/*****************************************************************/
        public class matchesCount
        {
            public int Won { get; set; }
            public int Lost {get; set;}
        }
/*****************************************************************/
        //This method counts total number of won and lost matches for a given teams list
        private List<matchesCount> countMatches(List<Team> t)
        {
            List<matchesCount> matches=new List<matchesCount>();
            int i=0;
            foreach(var team in t)
            {
                var wonMatches = _db.Matchs
                .Where(s => s.Team1.TeamId == team.TeamId || s.Team2.TeamId == team.TeamId) //w których drużyna grała
                .Select(s=> new {Won = (s.Team1.TeamName==team.TeamName && s.FinalScore1 > s.FinalScore2 || s.Team2.TeamName==team.TeamName && s.FinalScore2>s.FinalScore1)? 1 : 0})
                .ToList();

                matches.Add(new matchesCount());
                matches[i].Won=wonMatches.Where(s=>s.Won==1).Count();
                matches[i++].Lost=wonMatches.Where(s=>s.Won==0).Count();
            }
            return matches;
        }
/*****************************************************************/
        //Overloaded method for single team's won/lost matches counting
        private matchesCount countMatches(Team t)
        {
            matchesCount mc = new matchesCount();
            var wonMatches = _db.Matchs
            .Where(s => s.Team1.TeamId == t.TeamId || s.Team2.TeamId == t.TeamId) //w których drużyna grała
            .Select(s => new { Won = (s.Team1.TeamName == t.TeamName && s.FinalScore1 > s.FinalScore2 || s.Team2.TeamName == t.TeamName && s.FinalScore2 > s.FinalScore1) ? 1 : 0 })
            .ToList();

            mc.Won = wonMatches.Where(s => s.Won == 1).Count();
            mc.Lost = wonMatches.Where(s => s.Won == 0).Count();

            return mc;
        }
    }
}
